//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using OpenLS.Spreadsheet.Expressions;

namespace OpenLS.Spreadsheet
{
    internal class ArrayFormulaReference : Expression
    {
        private readonly ArrayFormula _arrayFormula;

        public ArrayFormulaReference(ArrayFormula arrayFormula)
        {
            _arrayFormula = arrayFormula;
        }
        internal override Expression Transposed(Cell target)
        {
           throw new NotImplementedException(); 
        }
        public override IEnumerable<Expression> GetSubExpressions()
        {
            yield return _arrayFormula.Expression;
        }

        public ArrayFormula ArrayFormula
        {
            get { return _arrayFormula; }
        }

        public override string GetText(TextContext context)
        {
            return ArrayFormula.Expression.GetText(context);
        }

        public override IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context)
        {
            return ArrayFormula.Expression.GetPrecedents(context);
        }

        protected override object GetObjectImp(EvaluationContext context)
        {
            var context2 = (CellEvaluationContext) context;
            context2.IsArray = true;
            IArray array = null;
            object result;
            if (context.Workbook.CalculationManager.ArrayFormulaCache.TryGetValue(ArrayFormula, out array))
            {
                result = array;
                var offset = context.Target.Address - ArrayFormula.Range.TopLeftCell.Address;
                return array[offset.Row, offset.Column];
            }
            result = ArrayFormula.Expression.GetObject(context);
            if (result is IArray)
            {
                array = (IArray) result;
                context.Workbook.CalculationManager.ArrayFormulaCache.Add(ArrayFormula, array);
                var offset = context.Target.Address - ArrayFormula.Range.TopLeftCell.Address;
                return array[offset.Row, offset.Column];
            }
            return result;

        }

        public override Expression Offset(CellRelativeAddress a)
        {
            throw new NotImplementedException();
        }
    }
}